package cn.tedu._03vehicle.base.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;

import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 网站限流的拦截器:单个IP访问不得超过三次
 */
@Slf4j
public class RateLimitInterceptor implements HandlerInterceptor {
    //限制最多访问次数阈值
    private static final int MAX_REQUEST_COUNT = 3;
    //限制时间窗口大小
    private static final int MAX_REQUEST_WINDOW_SIZE = 60;
    //用于计单个IP访问次数集合
    private final ConcurrentHashMap<String, Integer> clientCount = new ConcurrentHashMap<>();
    //用于计单个IP访问时间的集合
    private final ConcurrentHashMap<String, LocalDateTime> lastRequestTime = new ConcurrentHashMap<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.debug("进入网站限流的拦截器...");
        String clientIp = request.getRemoteAddr();
        LocalDateTime lastTime = lastRequestTime.get(clientIp);
        if (lastTime == null ||LocalDateTime.now().isAfter(lastTime.plusSeconds(MAX_REQUEST_WINDOW_SIZE))){
            lastRequestTime.put(clientIp, LocalDateTime.now());
            clientCount.put(clientIp, 0);
        }
        Integer i = clientCount.get(clientIp);
        i = i+1;
        clientCount.put(clientIp,i);
        if (i > MAX_REQUEST_COUNT) {
            throw new RuntimeException("访问过于频繁,请稍后再试");
        }
        return true;
    }
}
